<script setup lang='ts'>
import { useTokenStore } from '@/stores/token'
import { saveAudioService, extractFeatureService, copyMfccService, getFeatureExtractionResultService, stopFeatureExtractionService } from '@/api/model'
import type { UploadFile, UploadInstance } from 'element-plus'
import { useExtractFeatureTaskStore } from '@/stores/extractFeatureTask'
import { onUnmounted } from 'vue'

const tokenStore = useTokenStore()

const extractFeatureTaskStore = useExtractFeatureTaskStore()

//创建一个birdNumber用于存放输入的birdNumber
const birdNumber = ref()

const uploadRef = ref<UploadInstance>()

interface SaveAudioResult {
    message: string
}

//用于上传模型结果的对象
const saveAudioResult = ref<SaveAudioResult>(
    {
       message: 'default'
    }
)

// 上传成功的回调
// const handleUploadSoundSuccess = async (response, file, fileList) => {
//     // 获取鸟类编号
//     // const birdNumber = '0017' // 示例编号，可以通过 UI 动态设置

//     console.log("birdNumber.value:" + birdNumber.value)

//     try {
//         const saveAudioResponse = await saveAudio(file.raw, birdNumber.value)
//         if (saveAudioResponse.code === 200) {
//             ElMessage.success('上传成功')
//             saveAudioResult.value = saveAudioResponse.data
//         } else {
//             ElMessage.error(saveAudioResponse.data.msg ? saveAudioResponse.data.msg : '上传失败')
//         }
//     } catch (error) {
//         ElMessage.error('上传失败')
//     }
// }

//上传成功的回调
const handleUploadSoundSuccess = (response, file, fileList) => {

//识别成功，将识别结果赋值给recognitionResult
if(response.code == 200) {

    ElMessage.success('上传成功');
    saveAudioResult.value = response.data


}else{

    ElMessage.error(response.msg ? response.msg : '上传失败');

}


}


//调用后端接口实现保存鸟类音频文件到数据集文件夹中
const saveAudio = async (file, birdNumber) => {

    let result = await saveAudioService(file, birdNumber);

    console.log(result)

    if(result.code == 200){
        ElMessage.success("保存音频文件成功")
    }else{
        ElMessage.error(result.msg ? result.msg : '保存音频文件失败');
    }
    
    return result

}

// 用来控制提示任务运行状态的提示框显示与否
const taskRunning = ref(false);
const taskFinished = ref(false);

// 保存SSE连接的引用，以便在取消任务时关闭
let currentEventSource: EventSource | null = null;

// 关闭SSE连接的辅助函数
const closeSSEConnection = () => {
  if (currentEventSource) {
    console.log('关闭SSE连接');
    currentEventSource.close();
    currentEventSource = null;
  }
};

// 添加取消任务的功能
const cancelTask = async () => {
  if (!extractFeatureTaskStore.taskId) {
    ElMessage.warning('没有正在运行的任务');
    return;
  }

  try {
    const result = await stopFeatureExtractionService(extractFeatureTaskStore.taskId);
    
    if (result.code === 200) {
      ElMessage.success('任务已取消');
      taskRunning.value = false;
      taskFinished.value = false;
      extractFeatureTaskStore.taskId = null;

      // 关闭SSE连接
      closeSSEConnection();
    } else {
      ElMessage.error(result.msg || '取消任务失败');
    }
  } catch (error) {
    ElMessage.error('取消任务时发生错误');
    console.error('取消任务错误:', error);
  }
};

// TODO 这里还可以做一些取消任务之类的功能
// 建立 SSE 监听连接
const listenTaskResultBySSE = (taskId: string) => {
  // 先关闭之前的连接（如果有的话）
  closeSSEConnection();

  currentEventSource = new EventSource(`/api/extract-features/stream/${taskId}`);

  // 监听连接打开
  currentEventSource.onopen = (event) => {
    console.log('SSE连接已建立:', event);
  };

  // 监听消息
  currentEventSource.onmessage = (event) => {
    console.log('收到SSE消息:', event);
    console.log('消息数据:', event.data);
    console.log('消息类型:', event.type);

    try {
      const result = JSON.parse(event.data);
      console.log('解析后的消息:', result);
      
      // 根据消息内容判断任务状态
      if (result.message === '任务已启动') {
        console.log('任务已启动，继续监听...');
        // 任务已启动，继续监听，不关闭连接
        return;
      } else if (result.message === '任务已完成') {
        console.log('任务已完成！');
        ElMessage.success("特征提取任务已完成！");
        taskRunning.value = false;
        taskFinished.value = true;
        extractFeatureTaskStore.taskId = null;
        closeSSEConnection();
      } else {
        console.log('收到其他消息:', result);
        // 处理其他类型的消息
      }
    } catch (e) {
      console.error('JSON解析失败:', e);
      console.error('原始数据:', event.data);
    }
  };

  currentEventSource.addEventListener('complete', (event: MessageEvent) => {
    console.log('收到complete事件:', event);
    console.log('事件数据:', event.data);
    
    try {
      const result = JSON.parse(event.data);
      console.log('complete事件解析结果:', result);
      
      // 根据消息内容判断任务状态
      if (result.message === '任务已启动') {
        console.log('任务已启动，继续监听...');
        // 任务已启动，继续监听，不关闭连接
        return;
      } else if (result.message === 'Feature extraction and saving completed successfully') {
        console.log('任务已完成！');
        ElMessage.success("特征提取任务已完成！");
        taskRunning.value = false;
        taskFinished.value = true;
        extractFeatureTaskStore.taskId = null;
        closeSSEConnection();
      } else {
        console.log('收到其他消息:', result);
        // 处理其他类型的消息，但不关闭连接
      }
    } catch (e) {
      console.error('complete事件JSON解析失败:', e);
      console.error('原始数据:', event.data);
      ElMessage.error("解析推送结果失败");
    }finally{
      closeSSEConnection();
    }
  });

  currentEventSource.onerror = (err) => {
    console.error("SSE连接发生错误：", err);
    ElMessage.error("SSE 连接出错");
    taskRunning.value = false;
    taskFinished.value = false;
    extractFeatureTaskStore.taskId = null; // 清理任务ID
    closeSSEConnection(); // 出错时关闭
  };

  // 可选：离开页面时关闭 SSE
  onUnmounted(() => {
    closeSSEConnection();
  });
};


const extractFeature = async () => {
  let result = await extractFeatureService();

  if (result.code === 200) {
    const taskId = result.data;
    extractFeatureTaskStore.taskId = taskId;

    // 把token写入cookie，用于SSE的时候自动传给后端验证
    document.cookie = `token=${tokenStore.token}; path=/; max-age=3600`;

    ElMessage.success("提取特征任务已开启");
    // ElMessage.warning("特征提取过程需要3到5分钟，在此期间请勿离开本页面，请勿重复点击");

    taskRunning.value = true;
    taskFinished.value = false;

    // 旧版轮询逻辑（去除）
    // startTaskStatusCheck();

    // 新版：开始监听 SSE
    listenTaskResultBySSE(taskId);

  } else {
    ElMessage.error(result.msg || '启动提取特征任务失败');
  }
};

//复制npy文件，用新的训练集替换原来的训练集
const copyMfcc = async () => {

    let result = await copyMfccService();

    if(result.code == 200){
        ElMessage.success("更新训练集成功")
    }else{
        ElMessage.error(result.msg ? result.msg : '更新训练集失败');
    }

}

//查询任务状态
// const checkTaskStatus = async () => {
//   if (!extractFeatureTaskStore.taskId) {
//     console.error('No task ID found in the store.');
//     return;
//   }

//   let result = await getFeatureExtractionResultService(extractFeatureTaskStore.taskId)

//   //TODO 这里的result.data之后需要改成其他的判断标准
//   if(result.code === 200 && result.data === "processing"){

//     ElMessage.warning('提取特征任务执行中');
    
//   }else if(result.code === 200){

//     clearInterval(taskStatusInterval);
//     ElMessage.success('提取特征任务已完成');

//   }
//   else{

//     console.error(result.msg);
//     ElMessage.error("提取特征任务失败")

//   }

// }

// let taskStatusInterval: any;

// const startTaskStatusCheck = () => {
//   taskStatusInterval = setInterval(checkTaskStatus, 5000);
// }

// const stopTaskStatusCheck = () => {
//   if (taskStatusInterval) {
//     clearInterval(taskStatusInterval);
//   }
// }

// //在组件销毁时停止定时器
// onUnmounted(() => {
//   stopTaskStatusCheck();
// });

</script>

<template>
    <div class="container">
        
        birdNumber: <el-input class="birdNumber" v-model="birdNumber" placeholder="birdNumber"/>
        请先输入birdNumber再上传文件
        <br>
        <br>

        <el-upload 
        class="upload-demo" drag 
        action="/api/save-audio"
        :limit="1"
        :headers="{'token': tokenStore.token}"
        :on-success="handleUploadSoundSuccess"
        :data="{'birdNumber': birdNumber}"
            multiple>
            <el-icon class="el-icon--upload"><upload-filled /></el-icon>
            <div class="el-upload__text">
                Drop file here or <em>click to upload</em>
            </div>
            <template #tip>
                <div class="el-upload__tip">
                    上传鸟类音频文件并合并进数据集里
                </div>
                <div class="el-upload__tip">
                    （文件大小不超过50MB）
                </div>
            </template>
        </el-upload>
        <!-- <el-button class="ml-3" type="success" @click="submitUpload">
            upload to server
        </el-button> -->
        <div class="result" v-if=" saveAudioResult.message != 'default' ">
            <div>{{  saveAudioResult.message }}</div>
        </div>
        <div class="result-btn">
            <el-button type="primary" @click="extractFeature()">提取特征</el-button>
            <el-button type="primary" @click="copyMfcc()">更新训练集</el-button>
            <!-- TODO 取消任务之后再做吧有点复杂的 -->
            <!-- <el-button 
                v-if="taskRunning" 
                type="danger" 
                @click="cancelTask()"
                style="margin-left: 10px;">
                取消任务
            </el-button> -->
        </div>
        <el-alert
            v-if="taskRunning"
            title="特征提取任务执行中，预计需要 3~5 分钟，请不要离开页面或重复点击, 否则需要等待10分钟后链接超时重试"
            type="warning"
            show-icon
            :closable="false"
            style="margin-bottom: 20px"
        />
    </div>
</template>

<style scoped>
.container {
    display: flex;
    /* justify-content: center; */
    align-items: center;
    margin: 10px;
    padding: 10px;
    flex-direction: column;
}
.result {
    margin: 10px;
}
.result-btn {
    margin: 10px;
}
.birdNumber{
    width: 30%;
}
</style>